package com.zyao89.view;

import com.zyao89.view.zweb.ZWebConfig;
import com.zyao89.view.zweb.ZWebInstance;
import com.zyao89.view.zweb.constants.InjectionMode;
import com.zyao89.view.zweb.constants.ZWebConstant;
import com.zyao89.view.zweb.inter.IZWebHandler;
import com.zyao89.view.zweb.inter.IZWebMethodInterface;
import com.zyao89.view.zweb.inter.IZWebOnStateListener;
import com.zyao89.view.zweb.utils.ZLog;
import com.zyao89.view.zweb.views.IZWebView;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.webengine.ResourceResponse;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import okhttp3.*;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 首页
 *
 * @since 2021-06-07
 */
public class MainAbility extends Ability implements IZWebMethodInterface, IZWebOnStateListener,
        IZWebView.OnPageListener {
    private static final int ROTATE_ANIMATOR = 360;
    private static final int DURATION_ANIMATOR = 1000;
    private static final int LOOPED_COUNT_ANIMATOR = 20;

    private StackLayout mRootView;

    private final static String ROOT = "root";
    private final Map<String, String> mDatabase = new HashMap<>();
    private ZWebInstance mZWebInstance;
    private OkHttpClient mOkHttpClient;
    private RequireService mRequireService;
    private ParseMessage mParseMessage;
    private Image mLoadingImg;
    private AnimatorProperty mAnimatorProperty;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        getWindow().setStatusBarColor(Color.getIntColor("#48048d"));
        ZWebInstance.initContext(this);

        DirectionalLayout groupView = new DirectionalLayout(this);
        groupView.setLayoutConfig(new DirectionalLayout.LayoutConfig(
                DirectionalLayout.LayoutConfig.MATCH_PARENT,
                DirectionalLayout.LayoutConfig.MATCH_PARENT));
        groupView.setOrientation(Component.VERTICAL);
        groupView.setAlignment(LayoutAlignment.HORIZONTAL_CENTER);

        DirectionalLayout actionBarLayout = new DirectionalLayout(this);
        actionBarLayout.setLayoutConfig(new DirectionalLayout.LayoutConfig(
                DirectionalLayout.LayoutConfig.MATCH_PARENT, 150));
        ShapeElement element = new ShapeElement();
        element.setRgbColor(new RgbColor(72, 4, 141));
        actionBarLayout.setBackground(element);
        actionBarLayout.setAlignment(TableLayout.Alignment.ALIGNMENT_BOTTOM);

        Button refresh = new Button(this);
        refresh.setText("REFRESH");
        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(
                DirectionalLayout.LayoutConfig.MATCH_PARENT, 100);
        layoutConfig.setMargins(15, 25, 15, 25);
        refresh.setLayoutConfig(layoutConfig);
        refresh.setTextAlignment(TextAlignment.CENTER);
        refresh.setTextSize(16, Text.TextSizeType.FP);
        refresh.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                mRequireService.refresh();
            }
        });
        ShapeElement elementBtn = new ShapeElement();
        elementBtn.setRgbColor(new RgbColor(220, 220, 220));
        refresh.setBackground(elementBtn);
        actionBarLayout.addComponent(refresh);
        groupView.addComponent(actionBarLayout);

        mLoadingImg = new Image(getContext());
        mLoadingImg.setWidth(DirectionalLayout.LayoutConfig.MATCH_CONTENT);
        mLoadingImg.setHeight(DirectionalLayout.LayoutConfig.MATCH_CONTENT);
        mLoadingImg.setPixelMap(ResourceTable.Media_ic_loading);
        mLoadingImg.setMarginTop(500);
        mLoadingImg.setVisibility(Component.VISIBLE);
        mAnimatorProperty = mLoadingImg.createAnimatorProperty();
        mAnimatorProperty.rotate(ROTATE_ANIMATOR).setDuration(DURATION_ANIMATOR)
                .setLoopedCount(LOOPED_COUNT_ANIMATOR);

        mLoadingImg.setBindStateChangedListener(new Component.BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                mAnimatorProperty.start();
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {
            }
        });

        mRootView = new StackLayout(this);
        mRootView.setLayoutConfig(new ComponentContainer.LayoutConfig(
                ComponentContainer.LayoutConfig.MATCH_PARENT,
                ComponentContainer.LayoutConfig.MATCH_PARENT));
        mRootView.setVisibility(Component.HIDE);
        groupView.addComponent(mRootView);
        groupView.addComponent(mLoadingImg);

        initZWeb();

        super.setUIContent(groupView);

        initOkHttpClient();

        initRequireService();

        mZWebInstance.onActivityStart();
        mZWebInstance.setOnPageListener(this);
    }

    private void initZWeb() {
        ZWebConfig config = new ZWebConfig
                .Builder(ZWebConstant.MAIN_HTML)
                .setOnStateListener(this)
                .setNativeMethodImplement(this)
                .setInjectionMode(InjectionMode.VuePlugin)
                .autoInjectFramework()
                .autoInjectExtendsJS()
                .build();
        mZWebInstance = ZWebInstance.createInstance(config);
        mZWebInstance.onActivityCreate(mRootView);
        mParseMessage = new ParseMessage();
    }

    private void initOkHttpClient() {
        mOkHttpClient = new OkHttpClient.Builder().hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        }).build();
    }

    private void initRequireService() {
        mRequireService = mZWebInstance.create(RequireService.class);
    }

    @Override
    public void onZWebCreated(IZWebHandler zWebHandler, int width, int height) {
        boolean result = mRequireService.init3("{\"type\": \"application\", \"page\": \"1\"}");
        System.out.println("init 结果打印： " + result);

        final long millis = System.currentTimeMillis();
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                long time = System.currentTimeMillis() - millis;
                System.out.println(time);
                mRequireService.callA("我是一个延迟饭送的坚挺消息。。。", "小A你好啊！", time);
            }
        }, 5000);
    }

    @Override
    public void onZWebException(IZWebHandler zWebHandler, long errorCode, String message) {
        // JS如果有异常会在这里回调
    }

    @Override
    public void onZWebRequire(IZWebHandler zWebHandler, String url, String method, String data, String type, final IZRequireController controller) {
        // 这里可以实现原生网络请求
        Request request = new Request.Builder().url(url).build();
        Call call = mOkHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                controller.result(false, "请求失败啦。。。");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                controller.result(true, response.body().string());
            }
        });
    }

    @Override
    public void onZWebMessage(IZWebHandler zWebHandler, String cmd, String oJson, IZMessageController controller) {
        // 消息处理可以这样做
        controller.parseMessage(this.mParseMessage);
    }

    @Override
    public void onZWebDestroy(IZWebHandler zWebHandler) {
        // JS销毁
    }

    @Override
    public void onZWebLog(IZWebHandler zWebHandler, String type, String msg) {
        // JS打印
        ZLog.with(this).d("onLog ==> type: " + type + ", msg: " + msg);
    }

    @Override
    public void saveData(IZWebHandler zWebHandler, String key, String value, IZDatabaseController zController) {
        // 这里可以存数据库
        String result = mDatabase.put(key, value);
        if (result == null) {
            zController.result(false);
        } else {
            zController.result(true, result);
        }
    }

    @Override
    public void loadData(IZWebHandler zWebHandler, String key, IZDatabaseController zController) {
        // 这里可以取数据
        String result = mDatabase.get(key);
        if (result == null) {
            zController.result(false);
        } else {
            zController.result(true, result);
        }
    }

    @Override
    public void showLoading(IZWebHandler zWebHandler) {

    }

    @Override
    public void hideLoading(IZWebHandler zWebHandler) {

    }

    @Override
    public void tip(IZWebHandler zWebHandler, String msg) {
        new ToastDialog(this).setText(msg).show();
    }

    @Override
    protected void onActive() {
        mZWebInstance.onActivityResume();
        super.onActive();
    }

    @Override
    protected void onInactive() {
        mZWebInstance.onActivityPause();
        super.onInactive();
    }

    @Override
    protected void onBackground() {
        mZWebInstance.onActivityStop();
        super.onBackground();
    }

    @Override
    protected void onStop() {
        mZWebInstance.onActivityDestroy();
        super.onStop();
    }

    @Override
    public void onBackPressed() {
        if (!mZWebInstance.onActivityBack()) {
            super.onBackPressed();
        }
    }
    @Override
    public void onReceivedTitle(String title) {

    }

    @Override
    public void onPageStart(String url) {

    }

    @Override
    public void onPageFinish(String url, boolean canGoBack, boolean canGoForward) {
        if (url.substring(url.length() - 2).contains("#")){
            if (mAnimatorProperty != null) {
                mAnimatorProperty.stop();
                mAnimatorProperty.cancel();
                mAnimatorProperty = null;
            }
            mLoadingImg.setVisibility(Component.HIDE);
            mRootView.setVisibility(Component.VISIBLE);
        }
    }

    @Override
    public void onProgressChanged(int newProgress) {

    }

    @Override
    public ResourceResponse shouldInterceptRequest(String url) {
        return null;
    }
}
